package com.example.sherlockzhong.plush_v2.Models;

import com.example.sherlockzhong.plush_v2.R;
import com.example.sherlockzhong.plush_v2.Utils.StorageUtils;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.HashMap;

/**
 * 有三个方法，但是请按顺序使用
 * getWeatherHashMap() 方法会用到网络，需要保护机制
 * 优先返回从网络获取的信息
 * 如果没有网络，则会返回本地储存结果
 * 如果没有网络，也没有本地存储，则返回NULL
 *
 * @author DosonLeung
 * @Time 2014/9/19
 */

public class WeatherModel {

    private static String API_BAIDU_IP = "http://api.map.baidu.com/location/ip?ak=%s&coor=bd09ll0";
    private static String API_BAIDU_WEATHER = "http://api.map.baidu.com/telematics/v3/weather?location=%s&output=json&ak=%s";
    private static String API_BAIDU_EXART = "9xg9ZsCTnMIhwmX6YLak90bC";

    //the result of the WeatherModel
    private static String cityName = null;

    private static String httpGet(String url) throws Exception {
        String result = null;
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse httpResponse = httpClient.execute(httpGet);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = httpResponse.getEntity();
                result = (Buffer(entity.getContent())).toString();
                return result;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    private static HttpResponse httpResponseGet(String url) throws Exception {
        HttpClient httpClient = new DefaultHttpClient();
        HttpResponse httpResponse = null;
        try {
            HttpClientParams.setCookiePolicy(httpClient.getParams(), CookiePolicy.BROWSER_COMPATIBILITY);
            HttpGet get = new HttpGet(url);
            httpResponse = httpClient.execute(get);
            return httpResponse;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return httpResponse;
    }

    private static StringBuilder Buffer(InputStream putIn) {
        StringBuilder builder = new StringBuilder();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(putIn));
        try {
            for (String s = bufferedReader.readLine(); s != null; s = bufferedReader.readLine()) {
                builder.append(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return builder;
    }

    public static int getTime() {
        int week = Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 1;
        return week;
    }

    private static String connectBaiDuWeather() {
        String weatherGet = null;
        String get = String.format(API_BAIDU_IP, API_BAIDU_EXART);
        try {
            weatherGet = httpGet(get);
            return weatherGet;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return weatherGet;
    }

    private static String getCityName() {
        String BaiDuConnectResponse = connectBaiDuWeather();
        JSONObject weatherJson = null;
        String cityName = null;
        if (BaiDuConnectResponse != null)
            try {
                weatherJson = new JSONObject(BaiDuConnectResponse);
            } catch (Exception e) {
                e.printStackTrace();
            }
        try {
            JSONObject contentJson = new JSONObject(weatherJson.getString("content"));
            JSONObject provinceJson = new JSONObject(contentJson.getString("address_detail"));
            cityName = provinceJson.getString("city");
            if (cityName != null)
                saveCityName(cityName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cityName;
    }

    private static String getWeatherByCityName(String cityName) {
        StringBuilder weather = null;
        try {
            String get = String.format(API_BAIDU_WEATHER, cityName, "9xg9ZsCTnMIhwmX6YLak90bC");
            HttpResponse response = httpResponseGet(get);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                weather = Buffer(entity.getContent());
                return weather.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static HashMap<Integer, HashMap<String, String>> getHashMap() {
        HashMap<Integer, HashMap<String, String>> weatherHashMaps = null;
        cityName = getCityName();
        String weather;
        if (cityName != null) {
            weather = getWeatherByCityName(cityName);
            saveWeather(weather);
            if (weather != null) {
                weatherHashMaps = resolve(weather, cityName);
            }
        }
        return weatherHashMaps;
    }

    private static String getIcon(String weather) {
        String Icon = null;
        if (weather.contains("晴")) {
            Icon = String.valueOf(R.drawable.clear_morning);
        } else if (weather.contains("雪")) {
            Icon = String.valueOf(R.drawable.snowy);
        } else if (weather.contains("雷")) {
            Icon = String.valueOf(R.drawable.thunder);
        } else if (weather.contains("雨")) {
            Icon = String.valueOf(R.drawable.rainy_morning);
        } else if (weather.contains("云") || weather.contains("尘") ||
                weather.contains("沙") || weather.contains("霾")) {
            Icon = String.valueOf(R.drawable.cloudy_morning);
        }
        return Icon;
    }

    private static HashMap<Integer, HashMap<String, String>> resolve(String weathers, String cityName) {
        HashMap<Integer, HashMap<String, String>> weatherHashMaps = new HashMap<Integer, HashMap<String, String>>();
        HashMap<String, String> weatherHashMap = new HashMap<String, String>();

        try {
            JSONObject weatherJson = new JSONObject(weathers);
            JSONArray resultsJson = new JSONArray(weatherJson.getString("results"));
            JSONObject resultJson = new JSONObject(resultsJson.getJSONObject(0).toString());
            String pm25 = resultJson.getString("pm25");
            JSONArray jsonArray = new JSONArray(resultJson.getString("index"));
            String wearPoint;
            String seekPoint;
            String sportPoint;
            String uvaPoint;
            String wearPointZS;
            String seekPointZS;
            String sportPointZS;
            String uvaPointZS;
            if(jsonArray.length()==5){
                wearPoint = jsonArray.getJSONObject(0).getString("des");
                seekPoint = jsonArray.getJSONObject(2).getString("des");
                sportPoint = jsonArray.getJSONObject(3).getString("des");
                uvaPoint = jsonArray.getJSONObject(4).getString("des");
                wearPointZS = jsonArray.getJSONObject(0).getString("zs");
                seekPointZS = jsonArray.getJSONObject(2).getString("zs");
                sportPointZS = jsonArray.getJSONObject(3).getString("zs");
                uvaPointZS = jsonArray.getJSONObject(4).getString("zs");
            }else{
                wearPoint = jsonArray.getJSONObject(0).getString("des");
                seekPoint = jsonArray.getJSONObject(3).getString("des");
                sportPoint = jsonArray.getJSONObject(4).getString("des");
                uvaPoint = jsonArray.getJSONObject(5).getString("des");
                wearPointZS = jsonArray.getJSONObject(0).getString("zs");
                seekPointZS = jsonArray.getJSONObject(3).getString("zs");
                sportPointZS = jsonArray.getJSONObject(4).getString("zs");
                uvaPointZS = jsonArray.getJSONObject(5).getString("zs");
            }
            JSONArray jsonArrays = new JSONArray(resultJson.getString("weather_data"));
            int length = jsonArrays.length();
            for (int i = 0; i < 1; i++) {
                weatherHashMap = new HashMap<String, String>();
                weatherHashMap.put("cityName", cityName);
                weatherHashMap.put("weather", jsonArrays.getJSONObject(i).getString("weather"));
                String tem = jsonArrays.getJSONObject(i).getString("temperature");
                if (tem.indexOf("~") == -1) {
                    weatherHashMap.put("temperature", jsonArrays.getJSONObject(i).getString("temperature"));
                } else {
                    int a = tem.indexOf(" ~ ");
                    String one = tem.substring(0, a);
                    String two = tem.substring(a + 2, tem.length() - 1);
                    weatherHashMap.put("temperature", two + " ~ " + one);
                }
                weatherHashMap.put("wind", jsonArrays.getJSONObject(i).getString("wind"));
                String str = jsonArrays.getJSONObject(i).getString("date");//实时温度
                if (str.indexOf("℃") != -1) {
                    int a = str.indexOf("：");
                    int b = str.indexOf("℃");
                    str = str.substring(a + 1, b);
                } else {
                    str = "无";
                }
                weatherHashMap.put("date", str);
                weatherHashMap.put("pm2.5", pm25);
                weatherHashMap.put("wearPoint", wearPoint);
                weatherHashMap.put("seekPoint", seekPoint);
                weatherHashMap.put("sportPoint", sportPoint);
                weatherHashMap.put("uvaPoint", uvaPoint);
                weatherHashMap.put("wearPointZS", wearPointZS);
                weatherHashMap.put("seekPointZS", seekPointZS);
                weatherHashMap.put("sportPointZS", sportPointZS);
                weatherHashMap.put("uvaPointZS", uvaPointZS);
                weatherHashMaps.put(i, weatherHashMap);
            }
            for (int i = 1; i < length; i++) {
                String tem = jsonArrays.getJSONObject(i).getString("temperature");
                String weather = jsonArrays.getJSONObject(i).getString("weather");
                int a = tem.indexOf(" ~ ");
                String one = tem.substring(0, a);
                String two = tem.substring(a + 2, tem.length() - 1);
                weatherHashMap = new HashMap<String, String>();
                weatherHashMap.put("date", jsonArrays.getJSONObject(i).getString("date"));
                weatherHashMap.put("weather", jsonArrays.getJSONObject(i).getString("weather"));
                weatherHashMap.put("wind", jsonArrays.getJSONObject(i).getString("wind"));
                weatherHashMap.put("temperature", two + " ~ " + one);
                if (weather.equals("晴")) {
                    weatherHashMap.put("weatherPicture", String.valueOf(R.drawable.clear_morning));

                } else if (weather.indexOf("雪") != -1) {
                    weatherHashMap.put("weatherPicture", String.valueOf(R.drawable.snowy));
                } else if (weather.indexOf("雷") != -1) {
                    weatherHashMap.put("weatherPicture", String.valueOf(R.drawable.thunder));
                } else if (weather.indexOf("雨") != -1) {
                    weatherHashMap.put("weatherPicture", String.valueOf(R.drawable.rainy_morning));
                } else if (weather.indexOf("云") != -1 || weather.indexOf("尘") != -1 ||
                        weather.indexOf("沙") != -1 || weather.indexOf("霾") != -1) {
                    weatherHashMap.put("weatherPicture", String.valueOf(R.drawable.cloudy_morning));
                }
                weatherHashMaps.put(i, weatherHashMap);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return weatherHashMaps;
    }

    private static HashMap<String, String> format(HashMap<Integer, HashMap<String, String>> hashmap) {
        HashMap<String, String> weatherHashMap = new HashMap<String, String>();
        if (hashmap != null) {
            int index = getTime();
            String weekdays[] = new String[]{"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
            String today = weekdays[index % 7];
            String tomorrow = weekdays[(index + 1) % 7];
            String day_after_tomorrow = weekdays[(index + 2) % 7];
            String three_day_from_today = weekdays[(index + 3) % 7];
            String weatherFullAddress = hashmap.get(0).get("cityName");
            String weatherFullCondition = hashmap.get(0).get("weather");
            String weatherFullWind = hashmap.get(0).get("wind");
            String weatherFullTemperature = hashmap.get(0).get("date");
            if (weatherFullTemperature.equals("无")) {
                weatherFullTemperature = "--";
            } else {
                weatherFullTemperature += "°";
            }
            String weatherTomorrowText = tomorrow + "(" + hashmap.get(1).get("temperature") + ")";
            String weatherDayAfterTomorrowText = day_after_tomorrow + "(" + hashmap.get(2).get("temperature") + ")";
            String weatherThreeDaysFromToday = three_day_from_today + "(" + hashmap.get(3).get("temperature") + ")";
            weatherHashMap.put("Today", today);
            weatherHashMap.put("Tomorrow", tomorrow);
            weatherHashMap.put("DayAfterTomorrow", day_after_tomorrow);
            weatherHashMap.put("ThreeDayFromToday", three_day_from_today);
            weatherHashMap.put("Address", weatherFullAddress);
            weatherHashMap.put("Condition", weatherFullCondition);
            weatherHashMap.put("WindPower", weatherFullWind);
            weatherHashMap.put("Temperature", weatherFullTemperature);
            weatherHashMap.put("TomorrowTemperature", weatherTomorrowText);
            weatherHashMap.put("DayAfterTomorrowTemperature", weatherDayAfterTomorrowText);
            weatherHashMap.put("ThreeDaysFromTodayTemperature", weatherThreeDaysFromToday);
            weatherHashMap.put("TomorrowIcon", hashmap.get(1).get("weatherPicture"));
            weatherHashMap.put("DayAfterTomorrowIcon", hashmap.get(2).get("weatherPicture"));
            weatherHashMap.put("ThreeDaysFromTodayIcon", hashmap.get(3).get("weatherPicture"));
            weatherHashMap.put("pm2.5", hashmap.get(0).get("pm2.5"));
            weatherHashMap.put("Sport", hashmap.get(0).get("sportPoint"));
            weatherHashMap.put("Uva", hashmap.get(0).get("uvaPoint"));
            weatherHashMap.put("Cold", hashmap.get(0).get("seekPoint"));
            weatherHashMap.put("Dress", hashmap.get(0).get("wearPoint"));
            weatherHashMap.put("SportIndex", hashmap.get(0).get("sportPointZS"));
            weatherHashMap.put("UvaIndex", hashmap.get(0).get("uvaPointZS"));
            weatherHashMap.put("ColdIndex", hashmap.get(0).get("seekPointZS"));
            weatherHashMap.put("DressIndex", hashmap.get(0).get("wearPointZS"));
            String weatherIcon = getIcon(weatherFullCondition);
            weatherHashMap.put("TodayIcon", weatherIcon);
            return weatherHashMap;
        } else {
            return null;
        }
    }

    private static boolean saveCityName(String cityName) {
        return StorageUtils.saveAsFile("weatherAddress.json", cityName);
    }

    private static String retrieveCityName() {
        String cityName = null;
        if (StorageUtils.fileExists("weatherAddress.json")) {
            cityName = StorageUtils.retrieveFromFile("weatherAddress.json");
        }
        return cityName;
    }

    private static boolean saveWeather(String weather) {
        return StorageUtils.saveAsFile("Weather.json", weather);
    }

    private static HashMap<String, String> retrieveWeather() {
        HashMap<Integer, HashMap<String, String>> weatherHashMaps = null;
        HashMap<String, String> hashmap = null;
        String weather = null;
        cityName = retrieveCityName();
        if (cityName != null) {
            weather = StorageUtils.retrieveFromFile("Weather.json");
            weatherHashMaps = resolve(weather, cityName);
            return format(weatherHashMaps);
        } else {
            return hashmap;
        }
    }

    /**
     * @return HashMap<Integer,HashMap<String,String>> weatherHashMaps;
     */
    public static HashMap<String, String> getWeatherHashMap() {
        HashMap<String, String> weatherHashMap = null;
        HashMap<Integer, HashMap<String, String>> hashmap = null;
        hashmap = getHashMap();
        if (hashmap != null) {
            weatherHashMap = format(hashmap);
            return weatherHashMap;
        } else {
            weatherHashMap = retrieveWeather();
            return weatherHashMap;
        }
    }
}
